package com.vb.ecm.web.custom.drl;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.documentum.fc.client.IDfFolder;
import com.documentum.fc.client.IDfFormat;
import com.documentum.fc.client.IDfPersistentObject;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSysObject;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.DfId;
import com.documentum.fc.common.DfLoginInfo;
import com.documentum.fc.common.IDfLoginInfo;
import com.documentum.web.common.AcsService;
import com.documentum.web.common.ArgumentList;
import com.documentum.web.common.ClientNetworkLocationService;
import com.documentum.web.common.SessionState;
import com.documentum.web.common.URLEncoderCache;
import com.documentum.web.common.WrapperRuntimeException;
import com.documentum.web.form.control.Button;
import com.documentum.web.form.control.Checkbox;
import com.documentum.web.form.control.Label;
import com.documentum.web.form.control.Panel;
import com.documentum.web.formext.action.ActionService;
import com.documentum.web.formext.action.IActionCompleteListener;
import com.documentum.web.formext.component.Component;
import com.documentum.web.formext.config.ConfigService;
import com.documentum.web.formext.config.Context;
import com.documentum.web.formext.config.IConfigElement;
import com.documentum.web.formext.config.IConfigLookup;
import com.documentum.web.formext.control.docbase.DocbaseIcon;
import com.documentum.web.formext.docbase.ObjectCacheUtil;
import com.documentum.web.formext.docbase.TypeUtil;
import com.documentum.web.formext.session.AuthenticationService;
import com.documentum.web.formext.session.DocbaseUtils;
import com.documentum.web.formext.session.IAuthenticationService;
import com.documentum.web.formext.session.PasswordExpiredException;
import com.documentum.web.formext.session.SessionManagerHttpBinding;

public class DRLComponent extends Component {
	
	private static final Logger LOGGER = Logger.getLogger(DRLComponent.class);

	private class DRLLogoffOnComplete implements IActionCompleteListener {

		final DRLComponent this$0;

		public void onComplete(String strAction, boolean bSuccess, Map map) {
			doLogout("/component/logoff?afterLogoff=closeWindow");
		}

		private DRLLogoffOnComplete() {
			this$0 = DRLComponent.this;
			// super();
		}

	}

	private class SysObject {

		private String m_strObjectId;
		private String m_strObjectName;
		private String m_strObjectType;
		private String m_strFormat;
		private String m_strVersionLabels;
		private Context m_actionContext;
		private ArgumentList m_actionArgs;
		private Boolean m_canEdit;
		private Boolean m_canView;
		private static final String DRL_VIEW_ACTION = "drlview";
		private static final String DRL_EDIT_ACTION = "drledit";
		final DRLComponent this$0;

		public String getObjectName() {
			return m_strObjectName;
		}

		public String getObjectType() {
			return m_strObjectType;
		}

		public String getFormat() {
			return m_strFormat;
		}

		public String getVersionLabels() {
			return m_strVersionLabels;
		}

		public boolean canView() {
			if (m_canView == null) {
				m_canView = Boolean.valueOf(m_strObjectId != null && ActionService.queryExecute("drlview", m_actionArgs, m_actionContext, DRLComponent.this));
			}
			return m_canView.booleanValue();
		}

		public boolean canEdit() {
			if (m_canEdit == null) {
				m_canEdit = Boolean.valueOf(m_strObjectId != null && ActionService.queryExecute("drledit", m_actionArgs, m_actionContext, DRLComponent.this));
			}
			return m_canEdit.booleanValue();
		}

		public void doView() {
			if (m_strObjectId != null) {
				if (m_bUsingAnonymousAccount && !hasViewPermissions()) {
					doLogoutAndDispatchAction("drlview");
				} else {
					executeAction("drlview");
				}
			}
		}

		public void doEdit() {
			if (m_strObjectId != null) {
				if (m_bUsingAnonymousAccount && !hasEditPermissions()) {
					doLogoutAndDispatchAction("drledit");
				} else {
					executeAction("drledit");
				}
			}
		}

		// private void executeAction(String strActionId)
		private void executeAction(String strActionId) {

			initNetworkLocationControls();
			IActionCompleteListener completeListener = null;
			if (m_bUsingAnonymousAccount && m_bLogoffAnonymousAccounts) {
				System.out.println("navigateOnComplete");
				completeListener = new DRLLogoffOnComplete();
				m_actionArgs.add("navigateOnComplete", Boolean.FALSE.toString());
			}
			System.out.println("Before ActionService Execute");
			ActionService.execute(strActionId, m_actionArgs, m_actionContext, DRLComponent.this, completeListener);
		}

		private void doLogoutAndDispatchAction(String strActionId) {
			// StringBuffer logoffUrl = new
			// StringBuffer("/component/logoff?afterLogoff=forward&forwardUrl=");
			StringBuffer logoffUrl = new StringBuffer("/component/logoff?afterLogoff=closeWindow");
			logoffUrl.append(constructActionUrl(strActionId, m_actionArgs, true));
			doLogout(logoffUrl.toString());
		}

		private boolean hasEditPermissions() {
			boolean bHasEditPermissions = false;
			if (!canEdit()) {
				bHasEditPermissions = false;
			} else {
				bHasEditPermissions = hasPermissions(5);
			}
			return bHasEditPermissions;
		}

		private boolean hasViewPermissions() {
			boolean bHasViewPermissions = false;
			if (!canView()) {
				bHasViewPermissions = false;
			} else if ("dm_folder".equals(getObjectType())) {
				bHasViewPermissions = hasPermissions(2);
			} else {
				bHasViewPermissions = hasPermissions(3);
			}
			return bHasViewPermissions;
		}

		private boolean hasPermissions(int dfPermit) {
			boolean bHasPermissions = false;
			try {
				IDfSysObject sysObject = (IDfSysObject) ObjectCacheUtil.getObject(getDfSession(), m_strObjectId);
				if (sysObject != null) {
					int permit = sysObject.getPermit();
					bHasPermissions = permit >= dfPermit;
				}
			} catch (DfException dfe) {
				throw new WrapperRuntimeException(dfe);
			} catch (ClassCastException e) {
				throw new WrapperRuntimeException("Expecting IDfSysObject", e);
			}
			return bHasPermissions;
		}

		public boolean equals(SysObject object) {
			return m_strObjectId != null && object.m_strObjectId != null && m_strObjectId.equals(object.m_strObjectId);
		}

		private boolean isCurrentVersion() {
			return equals(m_objectCurrent);
		}

		SysObject(String strObjectId, String strVersionLabel, String strFormat) {
			this$0 = DRLComponent.this;

			m_strObjectId = null;
			m_strObjectName = "";
			m_strObjectType = "";
			m_strFormat = "";
			m_strVersionLabels = "";
			m_actionContext = null;
			m_actionArgs = null;
			m_canEdit = null;
			m_canView = null;
			try {
				IDfSession dfSession = getDfSession();
				IDfPersistentObject perObject = ObjectCacheUtil.getObject(dfSession, strObjectId);
				if (perObject instanceof IDfSysObject) {
					IDfSysObject sysObject = (IDfSysObject) perObject;
					if (strVersionLabel != null && strVersionLabel.length() > 0) {
						String strChronicleId = sysObject.getString("i_chronicle_id");
						StringBuffer buf = new StringBuffer(128);
						buf.append("dm_sysobject (all) where i_chronicle_id='").append(strChronicleId).append("' and any r_version_label='").append(strVersionLabel).append("'");
						sysObject = (IDfSysObject) dfSession.getObjectByQualification(buf.toString());
					}
					if (sysObject != null) {
						m_strObjectId = sysObject.getObjectId().getId();
						m_strObjectName = sysObject.getObjectName();
						m_strObjectType = sysObject.getType().getName();
						if (!(sysObject instanceof IDfFolder)) {
							if (strFormat == null || strFormat.length() == 0) {
								IDfFormat format = sysObject.getFormat();
								if (format != null) {
									strFormat = format.getName();
								}
							}
							m_strFormat = strFormat;
							StringBuffer buf = new StringBuffer(100);
							int nVersionLabel = sysObject.getVersionLabelCount();
							for (int iVersionLabel = 0; iVersionLabel < nVersionLabel; iVersionLabel++) {
								if (iVersionLabel > 0) {
									buf.append(", ");
								}
								buf.append(sysObject.getVersionLabel(iVersionLabel));
							}

							m_strVersionLabels = buf.toString();
						}
						m_actionArgs = new ArgumentList();
						m_actionArgs.add("objectId", m_strObjectId);
						m_actionArgs.add("contentType", strFormat);
						m_actionArgs.add("isVirtualDoc", Boolean.toString(sysObject.isVirtualDocument()));
						m_actionArgs.add("assembledFromId", sysObject.getAssembledFromId().getId());
						m_actionContext = new Context(getContext());
						m_actionContext.set("objectId", m_strObjectId);
					}
				}
			} catch (DfException e) {
				m_strObjectId = null;
			}
		}
	}

	private boolean m_showPermissionsErrorMessage;
	private boolean m_hideControls;
	private String m_strPermissionsErrorMessageNlsId;
	private String m_strObjectId;
	private String m_strVersionLabel;
	private String m_strFormat;
	private String m_time;
	private String m_hashCode;
	private String bocsID = null;

	private SysObject m_objectVersion;
	private SysObject m_objectCurrent;
	private SysObject m_objectActive;
	private boolean m_bUsingAnonymousAccount;
	private boolean m_bLogoffAnonymousAccounts;
	public static final String VIEW = "view";
	public static final String EDIT = "edit";
	public static final String CLOSE = "close";
	public static final String DETAILS_PANEL = "details";
	public static final String ERROR_PANEL = "error";
	public static final String ERROR_MESSAGE = "error_message";
	public static final String OBJ_VERSION = "object_version";
	public static final String OBJ_FORMAT = "object_format";
	public static final String OBJ_NAME = "object_name";
	public static final String OBJ_ICON = "object_icon";
	public static final String OPEN_CURRENT = "opencurrent";
	private static final String DRL_AUTHENTICATE_COMPONENT_ID = "drlauthenticate";
	private static final String DRL_USING_ANONYMOUS_ACCOUNT = "drlUsingAnonymousAccount";
	private static final String LOGOFF_ANONYMOUS_ACCOUNTS = "defaultaccounts.logoffoncomplete";
	// private static final String LOGOFF_AND_FORWARD_URL_PREFIX =
	// "/component/logoff?afterLogoff=forward&forwardUrl=";
	// private static final String LOGOFF_AND_CLOSE_URL =
	// "/component/logoff?afterLogoff=closeWindow";
	private static final String LOGOFF_AND_FORWARD_URL_PREFIX = "/component/logoff?afterLogoff=closeWindow";
	private static final String LOGOFF_AND_CLOSE_URL = "/component/logoff?afterLogoff=closeWindow";
	private static final String DEFAULT_URL_ENCODING = "UTF-8";
	private static final String DOCUMENT_PREFIX = "09";
	private static final String FOLDER_PREFIX = "0b";
	private static final String HAS_DRL_ACTION_MAP = "hasDRLActionMap";
	private boolean m_bIsDistributedDeployment = false;

	public DRLComponent() {
		m_showPermissionsErrorMessage = false;
		m_hideControls = false;
		m_strPermissionsErrorMessageNlsId = null;
		m_strObjectId = null;
		m_strVersionLabel = null;
		m_strFormat = null;
		m_objectVersion = null;
		m_objectCurrent = null;
		m_objectActive = null;
		m_bUsingAnonymousAccount = false;
		m_bLogoffAnonymousAccounts = true;
	}

	public void onInit(ArgumentList args) {
		super.onInit(args);

		m_strObjectId = args.get("objectId");
		m_strVersionLabel = args.get("versionLabel");
		m_strFormat = args.get("format");
		bocsID = args.get("parameter0");
		m_time = args.get("parameter1");
		m_hashCode = args.get("parameter2");
		System.out.println("m_strObjectId" + m_strObjectId);
		System.out.println("m_strVersionLabel" + m_strVersionLabel);
		System.out.println("m_strFormat" + m_strFormat);
		System.out.println("bocsID" + bocsID);
		System.out.println("m_time" + m_time);
		System.out.println("m_hashCode" + m_hashCode);

		if (m_strObjectId == null || m_strObjectId.length() == 0) {
			throw new IllegalArgumentException("DRLComponent requires an objectId.");
		}
		String strRequestedDocbase = DocbaseUtils.getDocbaseNameFromId(m_strObjectId);
		if (strRequestedDocbase == null) {
			showError("MSG_DOCBROKER_ERROR");
			return;
		}
		SessionManagerHttpBinding.setClientDocbase(strRequestedDocbase);
		if (!isAuthenticated(strRequestedDocbase)) {
			System.out.println("is Not Authenticated");
			attemptAnonymousLogin(strRequestedDocbase);
			setComponentJump("drlauthenticate", args, getContext());
		} else {
			System.out.println("is Authenticated");
			m_bUsingAnonymousAccount = Boolean.TRUE.equals(getPageContext().getRequest().getAttribute("drlUsingAnonymousAccount"));
			m_bLogoffAnonymousAccounts = Boolean.TRUE.equals(lookupBoolean("defaultaccounts.logoffoncomplete"));
			System.out.println("m_bUsingAnonymousAccount:" + m_bUsingAnonymousAccount);
			System.out.println("m_bLogoffAnonymousAccounts:" + m_bLogoffAnonymousAccounts);
			String time = m_time.trim();						 

			try {
				DateFormat formatter = new SimpleDateFormat("ddMMyyyyHHmm");
				Date Inputdate = (Date)formatter.parse(time);  
				System.out.println("InputDate:" +Inputdate );
				Long inputTimeM = Inputdate.getTime();
				Long currentTimeM = System.currentTimeMillis();
				System.out.println("Time Diff:" +(currentTimeM - inputTimeM)/60000);
				if (((currentTimeM - inputTimeM)/60000) <= 10) {

					if (MD5(time).equals(m_hashCode)) {

						if (!viewNonSysObj(m_strObjectId, args)) {
							System.out.println("viewNonSysObject False");
							updateDocbaseObjects();
							if (!m_objectActive.hasViewPermissions() && !m_objectActive.hasEditPermissions()) {
								processNoPrivilegesError();
								return;
							}
							setErrorPanelVisible(false);
							initDRLComponentControls();
							if (m_objectActive.isCurrentVersion() && m_objectActive.hasViewPermissions() && !m_objectActive.hasEditPermissions()) {
								m_objectActive.doView();
							}
						}
					} else {
						System.out.println("JUMP to Time Out Page due to Input Time not match with Hash Code MD5(time)Hash="+MD5(time)+" *HashCodeURL="+m_hashCode);
						setTimeoutPage();

					}
				} else {
					System.out.println("JUMP to Time Out Page due to sysdate, paramaeterdate diff exceeds 10 mins, parameterdate="+Inputdate);
					setTimeoutPage();
				}
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	protected void initNetworkLocationControls() {
		System.out.println("BOCS ID="+bocsID);
		if(bocsID == null || bocsID == "") {
			System.out.println("BOCS Not Required------");
		} else {
			System.out.println("BOCS Required++++++");
			m_bIsDistributedDeployment = false;
			if (AcsService.getInstance().isAcsReadTransferEnabled() || AcsService.getInstance().isAcsWriteTransferEnabled()) {
				List networkLocations = ClientNetworkLocationService.getInstance().getAvailableClientNetworkLocations();
				if (networkLocations == null || networkLocations.isEmpty()) {
					m_bIsDistributedDeployment = false;
				} else {
					
					
					if(bocsID ==null || bocsID.isEmpty()) {
						m_bIsDistributedDeployment = false;
						AcsService.getInstance().getAcsReadTransferPreferences().allowBocsTransfer(false);
						System.out.println("BOCS ID Empty***, So that Documents retrived from default BOCS"+bocsID);
						//IDfNetworkLocationEntry dfNetworkLocation = (IDfNetworkLocationEntry) networkLocations.get(0);
						//ClientNetworkLocationService.getInstance().setClientNetworkLocationId(("HQ-ECMBRV-UAT"));
						System.out.println("m_bIsDistributedDeployment:-" + m_bIsDistributedDeployment);
						System.out.println("Connected BOCS:" + ClientNetworkLocationService.getInstance().getClientNetworkLocationId());
					} else {
						m_bIsDistributedDeployment = true;
						AcsService.getInstance().getAcsReadTransferPreferences().allowBocsTransfer(true);
						System.out.println("BOCS ID NOT Empty, So that Documents retrived from "+bocsID);
						//IDfNetworkLocationEntry dfNetworkLocation = (IDfNetworkLocationEntry) networkLocations.get(0);
						ClientNetworkLocationService.getInstance().setClientNetworkLocationId((bocsID));
						System.out.println("m_bIsDistributedDeployment:-" + m_bIsDistributedDeployment);
						System.out.println("Connected BOCS:" + ClientNetworkLocationService.getInstance().getClientNetworkLocationId());
					}				
				}
			}
			
		}
	}

	private void setTimeoutPage() {
		// TODO Auto-generated method stub
		Checkbox openCurrCheckbox = (Checkbox) getControl("opencurrent", com.documentum.web.form.control.Checkbox.class);
		openCurrCheckbox.setVisible(false);
		Label objectNameLabel = (Label) getControl("object_name", com.documentum.web.form.control.Label.class);
		objectNameLabel.setVisible(false);
		Label objectVersionLabel = (Label) getControl("object_version", com.documentum.web.form.control.Label.class);
		objectVersionLabel.setVisible(false);
		Label objectFormatLabel = (Label) getControl("object_format", com.documentum.web.form.control.Label.class);
		objectFormatLabel.setVisible(false);
		DocbaseIcon docbaseIcon = (DocbaseIcon) getControl("object_icon", com.documentum.web.formext.control.docbase.DocbaseIcon.class);
		docbaseIcon.setVisible(false);

		setComponentPage("timeout");

	}
	
    private static String convertToHex(byte[] data) { 
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) { 
            int halfbyte = (data[i] >>> 4) & 0x0F;
            int two_halfs = 0;
            do { 
                if ((0 <= halfbyte) && (halfbyte <= 9)) 
                    buf.append((char) ('0' + halfbyte));
                else 
                    buf.append((char) ('a' + (halfbyte - 10)));
                halfbyte = data[i] & 0x0F;
            } while(two_halfs++ < 1);
        } 
        return buf.toString();
    } 
 
    public static String MD5(String text) 
    throws NoSuchAlgorithmException, UnsupportedEncodingException  { 
        MessageDigest md;
        md = MessageDigest.getInstance("MD5");
        byte[] md5hash = new byte[32];
        md.update(text.getBytes("iso-8859-1"), 0, text.length());
        md5hash = md.digest();
        return convertToHex(md5hash);
    } 			    
	 

	public boolean isAuthenticated(String strDocbase) {
		boolean bAuthenticated = false;
		if (SessionManagerHttpBinding.isConnectedToDocbase(strDocbase)) {
			bAuthenticated = true;
		} else {
			IAuthenticationService authService = AuthenticationService.getService();
			try {
				HttpServletRequest request = (HttpServletRequest) getPageContext().getRequest();
				HttpServletResponse response = (HttpServletResponse) getPageContext().getResponse();
				String authDocbase = authService.authenticate(request, response, strDocbase);
				System.out.println("authDocbase:" + authDocbase);
				if (authDocbase != null) {
					bAuthenticated = authDocbase.equals(strDocbase);
				}
			} catch (DfException ignore) {
			}
		}
		System.out.println("isAuthenticated" + bAuthenticated);
		return bAuthenticated;
	}

	public void onRender() {
		super.onRender();
		if (m_showPermissionsErrorMessage) {
			showMessage(m_strPermissionsErrorMessageNlsId, m_hideControls);
			m_showPermissionsErrorMessage = false;
		} else {
			setErrorPanelVisible(false);
		}
	}

	public void onOpenCurrent(Checkbox checkbox, ArgumentList args) {
		updateDocbaseObjects();
		updateDRLComponentButtons();
	}

	public void onViewClicked(Button button, ArgumentList args) {
		updateDocbaseObjects();
		if (m_objectActive.canView()) {
			m_objectActive.doView();
		} else {
			showWarning("MSG_NO_VIEW_PERMISSION");
			updateDRLComponentButtons();
		}
	}

	public void onEditClicked(Button button, ArgumentList args) {
		updateDocbaseObjects();
		if (m_objectActive.canEdit()) {
			m_objectActive.doEdit();
		} else {
			showWarning("MSG_NO_EDIT_PERMISSION");
			updateDRLComponentButtons();
		}
	}

	public void onCloseClicked(Button button, ArgumentList args) {
		if (m_bUsingAnonymousAccount && m_bLogoffAnonymousAccounts) {
	
			doLogout("/component/logoff?afterLogoff=closeWindow");
		} else {
			setComponentJump("main", args, getContext());
		}
	}

	public static String constructDRL(String strObjectId, String strVersionLabel, String strFormat, Component component) {
		if (component == null) {
			throw new IllegalArgumentException("component is mandatory");
		}
		if (strObjectId == null || strObjectId.length() == 0) {
			throw new IllegalArgumentException("Cannot create a bookmark without an objectId");
		}
		if (!hasDRLActions(strObjectId, null, component)) {
			return null;
		}
		StringBuffer buf = new StringBuffer(256);
		HttpServletRequest request = (HttpServletRequest) component.getPageContext().getRequest();
		buf.append(request.getContextPath()).append("/drl/objectId/").append(strObjectId);
		System.out.println("#############1111111##############>>>>>>>>>>>>>>>    " + buf.toString());
		if (strVersionLabel != null && strVersionLabel.length() > 0) {
			buf.append("/versionLabel/").append(strVersionLabel);
		}
		if (strFormat != null && strFormat.length() > 0) {
			buf.append("/format/").append(strFormat);
		}
		System.out.println("###########################>>>>>>>>>>>>>>>    " + buf.toString());

		return buf.toString();
	}

	public static boolean hasDRLActions(String strObjectId, String strObjectType, Component component) {
		if (component == null) {
			throw new IllegalArgumentException("component is mandatory");
		}
		if (strObjectId == null || strObjectId.length() == 0 || !(new DfId(strObjectId)).isObjectId()) {
			return false;
		}
		if (strObjectType == null || strObjectType.length() == 0) {
			try {
				strObjectType = TypeUtil.getObjectType(strObjectId);
			} catch (Exception e) {
				return false;
			}
		}
		return _hasDRLActions(strObjectId, strObjectType, component);
	}

	private static boolean _hasDRLActions(String strObjectId, String strObjectType, Component component) {
		Map cacheMap = (Map) SessionState.getAttribute("hasDRLActionMap");
		if (cacheMap == null) {
			cacheMap = new Hashtable();
			SessionState.setAttribute("hasDRLActionMap", cacheMap);
		}
		String key = (new StringBuilder()).append(SessionManagerHttpBinding.getCurrentDocbase()).append(strObjectType).toString();
		Boolean hasAction = (Boolean) cacheMap.get(key);
		if (hasAction == null) {
			hasAction = Boolean.valueOf(false);
			Context actionContext = new Context(component.getInitialContext());
			actionContext.set("objectId", strObjectId);
			actionContext.set("type", strObjectType);
			IConfigLookup lookup = ConfigService.getConfigLookup();
			if (lookup.lookupElement("action[id=drlview]", actionContext) != null || lookup.lookupElement("action[id=drledit]", actionContext) != null) {
				hasAction = Boolean.valueOf(true);
			}
			cacheMap.put(key, hasAction);
		}
		return hasAction.booleanValue();
	}

	protected String constructAuthenticatedDRL(String strObjectId, String strVersionLabel, String strFormat, boolean bEncode) {
		if (strObjectId == null || strObjectId.length() == 0) {
			throw new IllegalArgumentException("Cannot construct a DRL without an objectId");
		}
		StringBuffer buf = new StringBuffer(128);
		buf.append("/component/").append("drlauthenticate").append("?objectId=").append(strObjectId);
		if (strVersionLabel != null && strVersionLabel.length() > 0) {
			buf.append("&versionLabel=").append(strVersionLabel);
		}
		if (strFormat != null && strFormat.length() > 0) {
			buf.append("&format=").append(strFormat);
		}
		String url = makeUrl(getPageContext().getRequest(), buf.toString());
		if (bEncode) {
			try {
				url = URLEncoderCache.getEncodedString(url, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				throw new WrapperRuntimeException(e);
			}
		}
		return url;
	}

	protected void doLogout(String logoffUrl) {
		setComponentPage("logout");
		ArgumentList args = null;
		if (logoffUrl != null && logoffUrl.length() > 0) {
			args = new ArgumentList();
			args.add("homeurl", logoffUrl);
		}
		ActionService.execute("logout", args, getContext(), this, null);
	}

	private void attemptAnonymousLogin(String strRequestedDocbase) {
		boolean bAttemptAnonymousAuthentication = false;
		if (m_strObjectId != null && m_strObjectId.startsWith("09")) {
			bAttemptAnonymousAuthentication = true;
		}
		if (bAttemptAnonymousAuthentication) {
			System.out.println("bAttemptAnonymousAuthentication:" + bAttemptAnonymousAuthentication);
			boolean success = authenticateUsingAnonymousAccount(strRequestedDocbase);
			if (success) {
				System.out.println("authenticateUsingAnonymousAccount:" + success);
				getPageContext().getRequest().setAttribute("drlUsingAnonymousAccount", Boolean.TRUE);
			}
		}
	}

	private void showError(String strErrorNlsId) {
		m_showPermissionsErrorMessage = true;
		m_hideControls = true;
		m_strPermissionsErrorMessageNlsId = strErrorNlsId;
	}

	private void showWarning(String strErrorNlsId) {
		m_showPermissionsErrorMessage = true;
		m_hideControls = false;
		m_strPermissionsErrorMessageNlsId = strErrorNlsId;
	}

	private void showMessage(String strErrorNlsId, boolean hideControls) {
		if (hideControls) {
			Panel detailsPanel = (Panel) getControl("details", com.documentum.web.form.control.Panel.class);
			detailsPanel.setVisible(false);
			Button viewBtn = (Button) getControl("view", com.documentum.web.form.control.Button.class);
			viewBtn.setVisible(false);
			Button editBtn = (Button) getControl("edit", com.documentum.web.form.control.Button.class);
			editBtn.setVisible(false);
		}
		setErrorPanelVisible(true);
		Label error = (Label) getControl("error_message", com.documentum.web.form.control.Label.class);
		error.setLabel(getString(strErrorNlsId));
	}

	private void setErrorPanelVisible(boolean visible) {
		Panel errorPanel = (Panel) getControl("error", com.documentum.web.form.control.Panel.class);
		errorPanel.setVisible(visible);
	}

	private void processNoPrivilegesError() {
		boolean bAnonymousAccountNotPriviledged = false;
		if (m_strFormat == null) {
			if (m_objectCurrent.m_strObjectId == null) {
				if (m_strObjectId != null && m_strObjectId.startsWith("0b")) {
					showError("MSG_FOLDER_DOES_NOT_EXIST");
				} else if (m_bUsingAnonymousAccount) {
					bAnonymousAccountNotPriviledged = true;
				} else {
					showError("MSG_DOCUMENT_DOES_NOT_EXIST");
				}
			} else {
				showError("MSG_CONTENTLESS_OBJECT_ERROR");
			}
		} else if (m_bUsingAnonymousAccount) {
			bAnonymousAccountNotPriviledged = true;
		} else {
			showError("MSG_SUCURITY_ERROR");
		}
		if (m_bUsingAnonymousAccount && bAnonymousAccountNotPriviledged) {
			// StringBuffer logoffUrl = new
			// StringBuffer("/component/logoff?afterLogoff=forward&forwardUrl=");
			StringBuffer logoffUrl = new StringBuffer("/component/logoff?afterLogoff=closeWindow");
			logoffUrl.append(constructAuthenticatedDRL(m_strObjectId, m_strVersionLabel, m_strFormat, true));
			doLogout(logoffUrl.toString());
		}
	}

	private void updateDocbaseObjects() {
		m_objectVersion = new SysObject(m_strObjectId, m_strVersionLabel, m_strFormat);
		m_objectCurrent = new SysObject(m_strObjectId, "CURRENT", getInitArgs().get("format"));
		if (isCurrentVersionSelected()) {
			m_objectActive = m_objectCurrent;
		} else {
			m_objectActive = m_objectVersion;
		}
	}

	private void initDRLComponentControls() {
		Checkbox openCurrCheckbox = (Checkbox) getControl("opencurrent", com.documentum.web.form.control.Checkbox.class);
		boolean bIsOpenCurrentCheckBoxVisible = !m_objectVersion.isCurrentVersion();
		openCurrCheckbox.setVisible(bIsOpenCurrentCheckBoxVisible);
		Label objectNameLabel = (Label) getControl("object_name", com.documentum.web.form.control.Label.class);
		objectNameLabel.setLabel(m_objectVersion.getObjectName());
		Label objectVersionLabel = (Label) getControl("object_version", com.documentum.web.form.control.Label.class);
		objectVersionLabel.setLabel(m_objectVersion.getVersionLabels());
		Label objectFormatLabel = (Label) getControl("object_format", com.documentum.web.form.control.Label.class);
		objectFormatLabel.setLabel(m_objectVersion.getFormat());
		DocbaseIcon docbaseIcon = (DocbaseIcon) getControl("object_icon", com.documentum.web.formext.control.docbase.DocbaseIcon.class);
		docbaseIcon.setType(m_objectVersion.getObjectType());
		m_strFormat = m_strFormat == null ? m_objectVersion.getFormat() : m_strFormat;
		docbaseIcon.setFormat(m_strFormat);
		updateDRLComponentButtons();
	}

	private void updateDRLComponentButtons() {
		boolean bCanView = m_objectActive.hasViewPermissions();
		boolean bCanEdit = m_objectActive.hasEditPermissions();
		if (m_bUsingAnonymousAccount) {
			bCanView = true;
			bCanEdit = true;
		}
		Button viewBtn = (Button) getControl("view", com.documentum.web.form.control.Button.class);
		viewBtn.setEnabled(bCanView);
		Button editBtn = (Button) getControl("edit", com.documentum.web.form.control.Button.class);
		editBtn.setEnabled(bCanEdit);
		Button closeBtn = (Button) getControl("close", com.documentum.web.form.control.Button.class);
		closeBtn.setVisible(getCallerForm() != null);
		editBtn.setVisible(m_objectActive.getFormat() != null);
	}

	private boolean isCurrentVersionSelected() {
		Checkbox openCurrCheckbox = (Checkbox) getControl("opencurrent", com.documentum.web.form.control.Checkbox.class);
		return openCurrCheckbox.getValue();
	}

	private boolean viewNonSysObj(String strObjectId, ArgumentList args) {
		boolean fViewed = false;
		try {
			IDfSession dfSession = getDfSession();
			IDfPersistentObject docbaseObject = ObjectCacheUtil.getObject(dfSession, strObjectId);
			Context actionContext = new Context(getContext());
			actionContext.set("objectId", strObjectId);
			actionContext.set("type", docbaseObject.getType().getName());
			if (!(docbaseObject instanceof IDfSysObject) && ActionService.queryExecute("drlview", args, actionContext, this)) {
				fViewed = ActionService.execute("drlview", args, actionContext, this, null);
			}
		} catch (DfException e) {
		}
		return fViewed;
	}

	private boolean authenticateUsingAnonymousAccount(String strRequestedDocbase) {
		boolean bSuccessfullyAuthenticated = false;
		IDfLoginInfo loginInfo = getAnonymousAccountLoginInfo(strRequestedDocbase);
		if (loginInfo != null) {
			try {
				AuthenticationService.getService().login(getPageContext().getSession(), strRequestedDocbase, loginInfo.getUser(), loginInfo.getPassword(), loginInfo.getDomain());
				bSuccessfullyAuthenticated = true;
				System.out.println("bSuccessfullyAuthenticated:" + bSuccessfullyAuthenticated);
			} catch (PasswordExpiredException ignore) {
				bSuccessfullyAuthenticated = false;
			} catch (DfException ignore) {
				bSuccessfullyAuthenticated = false;
			}
		}
		return bSuccessfullyAuthenticated;
	}

	private IDfLoginInfo getAnonymousAccountLoginInfo(String strRequestedDocbase) {
		IDfLoginInfo loginInfo = null;
		IConfigLookup configLookup = ConfigService.getConfigLookup();
		Context ctx = getContext();
		System.out.println("getAnonymousAccountLoginInfo:" + strRequestedDocbase);
		if (strRequestedDocbase != null) {
			ctx = new Context(getContext());
			ctx.set("docbase", strRequestedDocbase);
		}
		IConfigElement accInfo = configLookup.lookupElement((new StringBuilder()).append("component[id=").append(getComponentId()).append("].defaultaccounts.account").toString(),
				ctx);
		if (accInfo == null) {
			accInfo = configLookup.lookupElement((new StringBuilder()).append("component[id=").append(getComponentId()).append("].defaultaccounts.defaultaccount").toString(), ctx);
			System.out.println("accInfo:" + accInfo);
		}
		if (accInfo != null) {
			String strUserId = accInfo.getChildElement("username").getValue();
			System.out.println("strUserId:" + strUserId);
			if (strUserId != null) {
				loginInfo = new DfLoginInfo();
				loginInfo.setUser(strUserId);
				IConfigElement newpwElem = accInfo.getChildElement("new-pw");
				System.out.println("new-pw:" + newpwElem.getValue());
				if (newpwElem != null) {
					try {
						// loginInfo.setPassword(TrustedAuthenticatorUtils.decryptByDES(newpwElem.getValue()));
						loginInfo.setPassword((newpwElem.getValue()));
					} catch (Exception e) {
						throw new WrapperRuntimeException(e);
					}
				} else {
					String strPassword = accInfo.getChildElement("password").getValue();
					// loginInfo.setPassword(TrustedAuthenticatorUtils.decrypt(strPassword));
					loginInfo.setPassword((strPassword));
				}
				String strDomain = accInfo.getChildElement("domain").getValue();
				if (strDomain != null && strDomain.length() > 0) {
					loginInfo.setDomain(strDomain);
				}
			}
		}
		return loginInfo;
	}

	private String constructActionUrl(String strActionId, ArgumentList args, boolean bEncode) {
		if (strActionId == null || strActionId.length() == 0) {
			throw new IllegalArgumentException("Action Id is required");
		}
		StringBuffer buf = new StringBuffer(256);
		buf.append("/action/").append(strActionId).append("?");
		if (args != null) {
			Iterator argIterator = args.nameIterator();
			boolean firstArg = true;
			while (argIterator.hasNext()) {
				String arg = (String) argIterator.next();
				String values[] = args.getValues(arg);
				int i = 0;
				while (i < values.length) {
					if (firstArg) {
						firstArg = false;
					} else {
						buf.append("&");
					}
					buf.append(arg).append("=").append(values[i]);
					i++;
				}
			}
		}
		String url = makeUrl(getPageContext().getRequest(), buf.toString());
		if (bEncode) {
			try {
				url = URLEncoderCache.getEncodedString(url, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				throw new WrapperRuntimeException(e);
			}
		}
		return url;
	}
}
